﻿#pragma once

// Debug Helper Function:
// myassert()
// mythrow(x)
// mythrow(x,y,z,a,b,c)

// 使错误报告中能看到抛出的数值
#ifdef _MSC_VER
	#pragma warning(push)
	#pragma warning(disable:4189)	// 局部变量已初始化但不引用
	#pragma optimize("", off)
	inline void mythrow(uint64_t err1, uint64_t err2 = 0, uint64_t err3 = 0, uint64_t err4 = 0, uint64_t err5 = 0, uint64_t err6 = 0)
	{
		uint64_t e1 = err1;
		uint64_t e2 = err2;
		uint64_t e3 = err3;
		uint64_t e4 = err4;
		uint64_t e5 = err5;
		uint64_t e6 = err6;
		throw std::runtime_error("crash");
	}
	inline void mythrow(const string& tid, uint64_t err1 = 0, uint64_t err2 = 0, uint64_t err3 = 0, uint64_t err4 = 0, uint64_t err5 = 0, uint64_t err6 = 0)
	{
		char tid_buf[41]={0};
		uint32_t size = my_min(tid.size(), 40);
		memcpy(tid_buf, tid.data(), size);

		uint64_t e1 = err1;
		uint64_t e2 = err2;
		uint64_t e3 = err3;
		uint64_t e4 = err4;
		uint64_t e5 = err5;
		uint64_t e6 = err6;
		throw std::runtime_error("crash");
	}
	#pragma optimize("", on)
	#pragma warning(pop)
#else
	inline void mythrow(uint64_t err1, uint64_t err2 = 0, uint64_t err3 = 0, uint64_t err4 = 0, uint64_t err5 = 0, uint64_t err6 = 0)
	{
//		uint64_t e1 = err1;
//		uint64_t e2 = err2;
//		uint64_t e3 = err3;
//		uint64_t e4 = err4;
//		uint64_t e5 = err5;
//		uint64_t e6 = err6;
		throw std::runtime_error("crash");
	}
	inline void mythrow(const string& tid, uint64_t err1 = 0, uint64_t err2 = 0, uint64_t err3 = 0, uint64_t err4 = 0, uint64_t err5 = 0, uint64_t err6 = 0)
	{
		//char tid_buf[41]={0};
		//uint32_t size = my_min(tid.size(), 40);
		//memcpy(tid_buf, tid.data(), size);

		//uint64_t e1 = err1;
		//uint64_t e2 = err2;
		//uint64_t e3 = err3;
		//uint64_t e4 = err4;
		//uint64_t e5 = err5;
		//uint64_t e6 = err6;
		throw std::runtime_error("crash");
	}
#endif

#ifdef _DEBUG
	
	#if defined MY_USE_LINUX
		#include <assert.h>
		#define myassert(exp) assert(exp)
	#else
		inline void __cdecl debugTrace(const char* format, ...)
		{
			va_list args;
			va_start(args, format);
			
		#ifdef _WIN32_WCE
			vprintf(format, args);
		#else // _WIN32
			char buf[512];
			_vsnprintf_s(buf, sizeof(buf), sizeof(buf)-1, format, args);
			::OutputDebugStringA(buf);
		#endif // _WIN32
			va_end(args);
		}
		#define mydebug debugTrace
		#define mydrun(exp) exp
	
		#define myassert(exp) 	do { if (!(exp)) { \
								/*_CrtSetReportMode(_CRT_ASSERT, _CRTDBG_MODE_DEBUG); */\
								mydebug("Assertion hit in %s(%d): " #exp "\n", __FILE__, __LINE__); \
								::DebugBreak(); } } while (0)
		#undef  ASSERT
		#define ASSERT(exp)		myassert(exp)
	#endif

#else //_DEBUG
	
	#ifdef MY_RELEASE_VERSION_INCL_DEBUG_CODE
	
		// for debug only
		inline void __cdecl debugTrace(const char* format, ...)
		{
			va_list args;
			va_start(args, format);
			
		#ifdef _WIN32_WCE
			vprintf(format, args);
		#else // _WIN32
			char buf[512];
			_vsnprintf_s(buf, sizeof(buf), sizeof(buf)-1, format, args);
			::OutputDebugStringA(buf);
		#endif // _WIN32
			va_end(args);
		}
	
		#define mydebug debugTrace
		#define mydrun(exp) exp
		#define myassert(exp) 	do { if (!(exp)) { throw(0); } } while (0)
		#undef  ASSERT
		#define ASSERT(exp)		myassert(exp)
	
	#else //MY_RELEASE_VERSION_INCL_DEBUG_CODE
	
		#define mydebug if (false) printf
		#define myassert(exp) 
		#define mydrun(exp)
	
	#endif //MY_RELEASE_VERSION_INCL_DEBUG_CODE

#endif //_DEBUG
